package com.bmob.lover.viewmodel.base

import androidx.lifecycle.viewModelScope
import com.kunminx.architecture.ui.callback.ProtectedUnPeekLiveData
import com.kunminx.architecture.ui.callback.UnPeekLiveData
import com.bmob.lover.app.ext.*
import com.bmob.lover.app.util.DeviceUtil
import com.bmob.lover.data.model.bean.*
import com.bmob.lover.data.repository.BmobRepository
import com.theone.mvvm.base.appContext
import com.theone.mvvm.core.app.ext.launch
import com.theone.mvvm.core.app.ext.msg
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
import rxhttp.wrapper.param.Method

//  ┏┓　　　┏┓
//┏┛┻━━━┛┻┓
//┃　　　　　　　┃
//┃　　　━　　　┃
//┃　┳┛　┗┳　┃
//┃　　　　　　　┃
//┃　　　┻　　　┃
//┃　　　　　　　┃
//┗━┓　　　┏━┛
//    ┃　　　┃                  神兽保佑
//    ┃　　　┃                  永无BUG！
//    ┃　　　┗━━━┓
//    ┃　　　　　　　┣┓
//    ┃　　　　　　　┏┛
//    ┗┓┓┏━┳┓┏┛
//      ┃┫┫　┃┫┫
//      ┗┻┛　┗┻┛
/**
 * @author The one
 * @date 2021-04-23 15:27
 * @describe TODO
 * @email 625805189@qq.com
 * @remark
 */
abstract class BaseBmobActionViewModel<T : BmobBean> : BaseBmobRequestViewModel<T>() {

    /**
     * 单个成功
     */
    private val objectSuccess: UnPeekLiveData<BmobResultBean> =
        UnPeekLiveData.Builder<BmobResultBean>().setAllowNullValue(true).create()

    /**
     * 批量成功
     */
    private val batchSuccess: UnPeekLiveData<String> =
        UnPeekLiveData.Builder<String>().setAllowNullValue(true).create()


    fun getBatchSuccessLiveDate(): ProtectedUnPeekLiveData<String> = batchSuccess
    fun getObjectSuccessLiveDate(): ProtectedUnPeekLiveData<BmobResultBean> = objectSuccess

    val isAdmin: Boolean by lazy {
        mUser?.username == "admin" && DeviceUtil.getDeviceId(appContext) == "86679004225177"
    }

    fun BaseLoverBean.setAuthorPointer() {
        author = mUser?.pointer()
    }

    fun BaseLoverBean.setLoverPointer() {
        setAuthorPointer()
        if (isBindLover)
            lover = mLover?.pointer()
    }

    fun T.save(loadingMsg: String? = "保存中", isUploadFile: Boolean = false) {
        action(Method.POST, getObjectPostJson(), loadingMsg, isUploadFile)
    }

    fun T.update(
        json: String,
        loadingMsg: String? = "更新中",
        isUploadFile: Boolean = false
    ) {
        action(Method.PUT, json, loadingMsg, isUploadFile)
    }


    fun T.delete(
        loadingMsg: String? = "删除中",
        isUploadFile: Boolean = false
    ) {
        action(Method.DELETE, "", loadingMsg, isUploadFile)
    }

    private fun T.action(
        method: Method,
        json: String,
        loadingMsg: String? = null,
        isUploadFile: Boolean = false
    ) {
        if (mUser.isTestAdmin(filterTable())) {
            return
        }
        viewModelScope.launch {
            BmobRepository.INSTANCE.doAction(getUrl(), method, mTableName, objectId, json).catch {
                onError(it.msg)
            }.onStart {
                loadingMsg?.let {
                    if (isUploadFile) {
                        showProgressDialog(it, 100, 100)
                    } else {
                        showLoadingDialog(it)
                    }
                }
            }.collect {
                it.msg = when (method) {
                    Method.POST -> "添加成功"
                    Method.PUT -> "更新成功"
                    else -> "删除成功"
                }
                objectSuccess.value = it
            }
            loadingMsg?.let {
                if (isUploadFile) {
                    hideProgressDialog()
                } else {
                    hideLoadingDialog()
                }
            }
            // 请求结束
            onFinally()
        }
    }

    fun List<T>.batchCreate(loadingMsg: String? = "保存中", isUploadFile: Boolean = false) {
        batch(Method.POST, loadingMsg, isUploadFile)
    }

    fun List<T>.batchUpdate(loadingMsg: String? = "更新中", isUploadFile: Boolean = false) {
        batch(Method.PUT, loadingMsg, isUploadFile)
    }

    fun List<T>.batchDelete(loadingMsg: String? = "删除中", isUploadFile: Boolean = false) {
        batch(Method.DELETE, loadingMsg, isUploadFile)
    }

    private fun List<T>.batch(method: Method, loadingMsg: String?, isUploadFile: Boolean) {
        if (mUser.isTestAdmin(filterTable())) {
            return
        }
        launch({
            batchSuccess.value = BmobRepository.INSTANCE.doBatch(getUrl(), method, this@batch)
        }, {
            onError(it.msg)
        }, {
            loadingMsg?.let {
                if (isUploadFile) {
                    showProgressDialog(it, 100, 100)
                } else {
                    showLoadingDialog(it)
                }
            }
        }, {
            // 请求结束
            onFinally()
            loadingMsg?.let {
                if (isUploadFile) {
                    hideProgressDialog()
                } else {
                    hideLoadingDialog()
                }
            }
        }
        )
    }

    private fun filterTable(): Boolean {
        return when (mTableName) {
            "Log" -> false
            "UserLocation" -> false
            else -> true
        }
    }

    override fun requestServer() {

    }

}